Skip to content

Fix CLI handshake on Windows named pipes with newline framing - #31

Open
freetag369 wants to merge 1 commit into
diffusionstudio:mainfrom
freetag369:fix/windows-named-pipe-handshake
Open

Fix CLI handshake on Windows named pipes with newline framing#31
freetag369 wants to merge 1 commit into
diffusionstudio:mainfrom
freetag369:fix/windows-named-pipe-handshake

Conversation

@freetag369

Copy link
Copy Markdown

Problem

On Windows, every dapi command that connects to the desktop app fails with:

Unexpected end of JSON input

The CLI handshake frames its messages by half-closing the socket:

  • the client (apps/cli/src/cli-client.ts) writes the handshake JSON, calls sock.end(), and parses the reply on 'end';
  • the server (apps/desktop/src/cli-server.ts) buffers until 'end', then handles the handshake and replies.

On Unix domain sockets this works because the connection stays half-open after end(). Windows named pipes (\\.\pipe\diffusion-studio) do not support half-open connections: the client's end() tears the whole pipe down, the reply never arrives, and the client parses an empty buffer.

Fix

Switch the handshake to newline framing, keeping the old half-close path working:

  • Client: write JSON + "\n" without half-closing, and resolve as soon as a newline-terminated reply arrives. If the peer closes without a trailing newline (an older server on Unix), fall back to parsing the buffered data on 'end' as before.
  • Server: handle the handshake as soon as the first newline arrives, and terminate replies with "\n". Clients that still frame by half-closing are handled on 'end' as before.

So new and old peers interoperate in both directions on Unix, and on Windows — where both sides ship together (app + bundled CLI) — the handshake now completes.

Testing

  • Windows 11 (10.0.26200), Node v22.23.1: before this change, dapi mount <file> (or any command that connects to the app) always failed with Unexpected end of JSON input; with it, the full mount → node capturenode render flow works against a real project.
  • npm run check (tsc --noEmit) passes in apps/desktop; apps/cli bundles cleanly with esbuild.

Notes

There are a couple of further Windows papercuts in the dev tooling (scripts/dev-desktop.mjs spawnSync npm ENOENT, chmod in the CLI build script) — reported separately in #30 since they're independent of this fix.

🤖 Generated with Claude Code

The CLI handshake framed its messages by half-closing the socket: the
client wrote the handshake and called sock.end(), then parsed the reply
on 'end'. Windows named pipes (\\.\pipe\diffusion-studio) do not support
half-open connections, so end() tears the whole pipe down before the app
can reply, the client reads an empty buffer, and every dapi command that
connects to the app fails with "Unexpected end of JSON input".

Frame the handshake with a newline instead: the client writes the JSON
followed by "\n" and keeps the socket open; the server answers as soon
as the first line arrives and terminates its reply with "\n". Peers that
still frame by half-closing are handled on 'end' on both sides, so new
clients and servers stay compatible with old ones on Unix sockets.

Repro (Windows 11, Node 22): launch the desktop app, then run any dapi
command that talks to it (e.g. `dapi mount <file>`). Before this change
the handshake always fails; after it, it succeeds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

@freetag369 is attempting to deploy a commit to the Diffusion Studio Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant